//COMHAN.C
//Authors: Rebecca Rush, Steven Andryzcik, Joseph Craig, James McKowen
//Version 1.0 09/15/11

#include <stdio.h>
#include "mpx_supt.h"
#include <stdlib.h>
#include <string.h>
#include <limits.h>

#define BUFFER_SIZE 200
#define DEFAULT_DIRECTORY "."
#define DISPLAY_AT_A_TIME 2
#define MAX_ARGS 20
#define NUM_FUNCTIONS 8
#define COMMAND_LENGTH 20

date_rec *date_p;
void displayDate(int argc, char **argv);
void displayDateWord(int argc, char **argv);
void version(int argc, char **argv);
void changeDate(int argc, char **argv);
void quit(int argc, char **argv);
void help (int argc, char **argv);
void directory(int argc, char **argv);


// Help
// Lists all functions available in the system
// or displays information on a specifc function.
// Paramaters: argc, argv
// Returns: void
// This aglorithm uses selection statements to determine
// if they are trying to access the main help function or
// the help function for individual functions.

void help (int argc, char **argv) {

  FILE *inFilePtr;
  char ending [] = ".txt";
  int sizeFile;
  char fileLine[128];

  //Accessing broad help function

  if (argc > 1) {

	printf("This function takes zero or one argument. Type \"help\" for more information.\n");
	return;
	
  }

  if(argc == 0)
    {
      char helpFilename[] = "help.txt";

      if((inFilePtr = fopen(helpFilename, "r")) != NULL)
	{
	  while(fgets (fileLine, sizeof( fileLine), inFilePtr) != NULL)
	    {
	      printf("%s", fileLine);
	    }
	  }
      else{
	printf("Help file for command list not found.");
      }

      printf("\n");

    }
  //Accessing specialized help functions
  else if(argc == 1)
    {
      char *name = argv[0];
      char *filename = malloc(strlen(name) + strlen(ending) + 2);
      strcpy(filename, name);
      strcat(filename, ending);

	  if (strlen(filename) > 10)
		strcpy(filename+6, "~1.txt\0");


      if((inFilePtr = fopen(filename, "r")) != NULL)
	{

	  while(fgets (fileLine, sizeof fileLine, inFilePtr) != NULL)
	    {
	      printf("%s", fileLine);
	    }
	}

	else printf("Help file not found for command \"%s\".\n", argv[0]);

    } else
	printf("Usage: help -or- help command\n");
}

// displayDate
// Displays the current date in numerical format.
// Parameters: argc, argv - neither are used to make this function work.
// Returns: void
// Uses the system function for get date.

void displayDate (int argc, char **argv) {

     argc = argc;
     argv = argv;

     sys_get_date(date_p); //This is the MPX support routine needed to get the
			   //date
     printf("%d/%d/%d\n", date_p->month, date_p->day, date_p->year);

}

// displayDateWord
// Is the same as displayDate(), it just converts the month
// into the word for that month
// Parameters: argc, argv - neither are used to make this function work.
// Uses the system function for get date.

void displayDateWord (int argc, char **argv) {

     argc = argc;
     argv = argv;

     sys_get_date(date_p);

     printf("The Current Date Set:\n");
     printf("MONTH:  ");
     if(date_p->month == 1)
	printf("January\n");
     else if(date_p->month == 2)
	printf("February\n");
     else if(date_p->month == 3)
	printf("March\n");
     else if(date_p->month == 4)
	printf("April\n");
     else if(date_p->month == 5)
	printf("May\n");
     else if(date_p->month == 6)
	printf("June\n");
     else if(date_p->month == 7)
	printf("July\n");
     else if(date_p->month == 8)
	printf("August\n");
     else if(date_p->month == 9)
	printf("September\n");
     else if(date_p->month == 10)
	printf("October\n");
     else if(date_p->month == 11)
	printf("November\n");
     else if(date_p->month == 12)
       printf("December\n");

     printf("DAY:    %d\n", date_p->day);
     printf("YEAR:   %d\n", date_p->year);

}

// chageDate
// Sets the date to the variables that are passed to it.
// Parameters: month, day, year
// Returns: void
// Uses the system function save_date.

void changeDate(int argc, char **argv)
{
  int month = atoi(argv[0]);
  int day =  atoi(argv[1]);

  int year = 1;

  int temp = 1;

  date_rec reset;
  date_rec *save_date;

  while( argv[2] == '0')
  {
     argv[2]++;
  }
  if(strlen == 0)
  {
     printf("The year can not be zero\n");
     return;
  }
  if(strlen(argv[2]) > 4)
  {
     printf("The year is too long to be set.\n");
     return;
  }

  year = atol(argv[2]);

  printf("Date to be changed: ");
  displayDate(0, NULL);
  printf("\n");


  save_date->month = month;
  save_date->day = day;
  save_date->year = year;

     //checking to make sure the variables passed to the function are within
     //the correct constraints

     if (argc > 3)
     {
     printf("Note: function only requires 3 arguments. Type \"help date\" for more info.\n\n");

     }

     if(month < 1 || month > 12) //checking the month
     {
	 printf("Values for 'month' must be between 1 and 12\n");
	 return;
     }

     if(day < 1 || day > 31) //checking the day
     {
	 printf("Acceptable values for 'days' in this month are between 1 and 31\n");
	 return;
     }

     if (year < 0)
     {
	 printf("Error: Year must be > 0.\n");
	 return;
	 }

     //checking the 30 day max for certain months

     if((day > 30) && (month == 4 || month == 6 || month == 9 || month == 11))
     {
	 printf("Acceptable values for 'days' in this month are between 1 and 30\n");
	 return;
     }

     if(month == 2) //checking for february problems and leap year
     {
	 if((year%4 != 0) && day > 28)
	 {
	     printf("It is not a leap year.\n");
	     return;
	 }
	 else if((year%4 == 0) && day > 29)
	 {
	     printf("There are only 29 days in February on leap year.\n");
	     return;
	 }
     }

     temp = sys_set_date(save_date);

     //if(save_date->month == date_p->month && save_date->day == date_p->day && save_date->year == date_p->year)
     //{
     //	 temp = 0;
     //}

     if(temp != 0)
     {
	 printf("You have entered an invalid Date.\n");

     } else {

	 printf("Date Set Successfully!\n");
	 printf("\n");
	 printf("The new current date is:  ");
	 displayDate(0, NULL);
	 printf("\n");

     }

     argc = argc;
}

// Version
// Displays the current version, along with the system authors.
// Parameters: argc, argv - neither are used to make this function run.
// Returns: void
// Uses the printf function.
void version (int argc, char **argv) {

     argc = argc;
     argv = argv;

     if (argc > 0)
	printf("Note: this function requires 0 arguments.\n\n");

     printf("VERSION INFORMATION\n");
     printf("\n");
     printf("Version: 1\n");
     printf("\n");
     printf("Deliverable: R1\n");
     printf("\n");
     printf("Authors:\n");
     printf("Rebecca Rush\n");
     printf("James McKowen\n");
     printf("Joseph Craig\n");
     printf("Steven Andryzcik\n");
     printf("\n");
     printf("\n");
     printf("Last Modified: 9-15-2011\n");

}

// directory
// Lists all files with mpx extensions.
// Parameters: argc, argv - not needed for this function.
// Returns: void
// First uses the system function sys_open_dir to open the directory
// then uses the system function sys_get_entry to pull the different
// files and check to see if they have the mpx extension
void directory (int argc, char **argv) {

	char *directory;
	int  result;

	if (argc > 1) {
		printf("\n\tUsage: directory {path}\n\n");
		return;
	}

	// Attempt to open the user's requested directory.
	directory = (argc == 0 ? DEFAULT_DIRECTORY : argv[0]);
	result = sys_open_dir(directory);

	// If the attempt succeeded, print the files in the directory and their
	// sizes to the standard output.
	if (result == OK) {
		char  filename[BUFFER_SIZE];
		int   written = 0;
		short pause = 0;
		long  file_size;

		while (
			sys_get_entry(
				filename,
				BUFFER_SIZE,
				&file_size
			) != ERR_SUP_NOENTR
		) {
			// If a specific number of lines have been printed, pause the
			// printing so the user can catch up.
			if (pause) {
				system("pause");
				gotoxy(1, wherey() - 2);
				printf("                               ");
				gotoxy(1, wherey());
				pause = 0;
			}

			// Write the file and its size to the terminal.
			printf("%-20s%d bytes\n", filename, file_size);

			// If a specific number of lines have been printed, set the pause
			// flag.
			if ((++written % DISPLAY_AT_A_TIME) == 0) {
				pause = 1;
			}
		}

		// If no files were printed, write a message to the screen.
		if (written == 0) {
			printf("No .MPX files were found in the directory.\n");
		}
	}

	// Otherwise, print error messages explaining the failure.
	else {
		switch (result) {

			case ERR_SUP_DIROPN:
				printf(
					"\n\tError: could not open the directory \"%s\".\n\n",
					directory
				);
				break;

			case ERR_SUP_INVDIR:
				printf(
					"\n\tError: \"%s\" is an invalid directory.\n\n",
					directory
				);
				break;
		}
	}

	sys_close_dir();

}

// quit
// Exits the system.
// Parameters: argc, argv - not needed to use this command.
// Returns: void.
// Uses the system function sys_req to make sure that the user
// wants to exit the system.

void quit (int argc, char **argv) {

  char buf[4];
  int buf_size = 4;
  char answer = 'y';

  printf("Are you sure you want to exit? (y/*)\n\n");
  printf("> ");

  sys_req(READ, TERMINAL, buf, &buf_size);

  if(answer==buf[0])
    {
	printf("\nThanks for using MPX.\n\n");
	system("pause");
	sys_exit();
    }

    argc = argc;
    argv = argv;
}

// run
// The command line interface that allows the user to input a function
// and then calls that particular function.
// Parameters: none
// Return: void
// The function reads the command in through the command line and
// sends its parameters to the correct function to be processed

void run () {

	int found;
	char buffer[BUFFER_SIZE];
	char separator[]=" ";
	char *command, *token;
	int size=BUFFER_SIZE;
	int numargs=0;
	int i;
	char *args[MAX_ARGS];

	char function_names[NUM_FUNCTIONS][COMMAND_LENGTH] = {"help", "version", "displayDate", "displayDateWord", "changeDate", "directory", "quit"};
	int (*functions[NUM_FUNCTIONS])(int, char**) = {&help, &version, &displayDate, &displayDateWord, &changeDate, &directory, &quit};

	system("cls");

	printf(".::       .::.:::::::  .::      .::\n.: .::   .:::.::    .:: .::   .::\n.:: .:: . .::.::    .::  .:: .::\n.::  .::  .::.:::::::      .::\n.::   .:  .::.::         .:: .::\n.::       .::.::        .::   .::\n.::       .::.::       .::      .::\n\n");

	printf("An MPX can have 50 arguments and be as long as 200 characters.\n\nType \"help\" for more information.\n\n");

	while (1) {

		numargs=0;

		printf("> ");
		sys_req(READ, TERMINAL, buffer, &size);
		buffer[strlen(buffer)-1]='\0';
		command = strtok(buffer, separator);

		token = strtok (NULL, separator);

		while (token != NULL) {
			numargs++;
			args[numargs-1]=token;
			token = strtok(NULL,separator);
		}

		found=0;

		for (i = 0; i < NUM_FUNCTIONS; i++) {

		       if (strcmp(function_names[i], command) == 0) {
			       printf("\n");
			       functions[i](numargs, args);
			       printf("\n");
			       found=1;
		       }
		}

		if (found == 0 && strcmp(command, NULL) != 0)
			printf("\nSorry, but the command you entered, \"%s\", seems to be unimplemented.\n\n", command);

	}

}


// main
// Starts the system running
// Parameters: none
// Returns: int
// Calls the run function
int main () {

	sys_init(MODULE_R1);
	run();
	return 0;
}
